import random

from django.conf import settings
from django.shortcuts import render
from django_redis import get_redis_connection
from itsdangerous import TimedJSONWebSignatureSerializer
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import User
from rest_framework.generics import GenericAPIView,CreateAPIView, RetrieveAPIView, UpdateAPIView
from rest_framework import mixins
from . import serializers
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import GenericViewSet

class CheckUsernameView(APIView):
    def get(self,request,username):

        #1,根据用户名查询,用户数量
        count = User.objects.filter(username=username).count()

        #2,返回响应
        data = {
            "count":count
        }
        return Response(data,status=status.HTTP_200_OK)

class CheckMobileView(APIView):
    def get(self,request,mobile):

        #1,根据手机号查询,用户数量
        count = User.objects.filter(mobile=mobile).count()

        #2,返回响应
        data = {
            "count":count
        }
        return Response(data,status=status.HTTP_200_OK)

class RegisterUserView(CreateAPIView):
    serializer_class = serializers.RegisterUserSerializer

    # def post(self,request):
        #一, 只继承自了GenericAPIView
        # #1,获取参数
        # dict_data = request.data
        #
        # #2,创建序列化器,校验
        # serializer =  self.get_serializer(data=dict_data)
        # serializer.is_valid(raise_exception=True)
        #
        # #3,数据入库
        # serializer.save()
        #
        # #4,返回响应
        # return Response(serializer.data,status=status.HTTP_201_CREATED)

        #二,使用了mixin + GenericAPIView
        # return self.create(request)

class UserInfoView(RetrieveAPIView):
    serializer_class = serializers.UserInfoSerializer

    permission_classes = [IsAuthenticated] # 认证用户

    def get_object(self):
        return self.request.user

    # def get(self, request):
    #　一,单纯使用二级试图实现
    #     # 1,获取用户对象(或者request.user）
    #     # user = request.user
    #     self.get_object()
    #
    #     # 2,创建序列化对象
    #     serializer = self.get_serializer(instance=user)
    #
    #     # 3,返回数据
    #     return Response(serializer.data)

    # 二, 二级试图配合mixin
    #     return self.retrieve(request)

class EmailSendView(UpdateAPIView):
    serializer_class = serializers.EmailSendSerializer
    permission_classes = [IsAuthenticated] # 认证用户

    def get_object(self):
        return self.request.user

    # def put(self, request):
    #     # 1,获取数据
    #     dict_data = request.date
    #     user = self.get_object()
    #
    #     # 2,获取序列化器
    #     serializer = self.get_serializer(instance=user, data=dict_data)
    #
    #
    #     # 3,校验, 入库
    #     serializer.is_valid(raise_exception=True)
    #     serializer.save()
    #
    #     # 4,返回
    #     return Response(serializer.data)
    #
    #     return self.update(request)

class EmailActiveView(APIView):
    def get(self, request):
        # 1,获取参数token
        token = request.query_params.get("token")

        # 2,为空校验
        if not token:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 3,解密token
        user = User.decode_token(token)
        if not user:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 4,数据入库(修改email_active属性)
        user.email_active = True
        user.save()

        # 5,返回响应
        return Response(status=status.HTTP_200_OK)

class AddressView(mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, GenericViewSet):
    serializer_class = serializers.AddressSerializer

    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return self.request.user.addresses.filter(is_deleted=False)

    def list(self, request):

        # 1,获取用户地址信息
        queryset = self.get_queryset()

        # 2,获取序列化器
        serializer = self.get_serializer(instance=queryset, many=True)

        # 3,返回
        return Response({
            "addresses": serializer.data,
            "limit": 20,
            "default_address_id": request.user.default_address_id
        })

    # 1,重写地址创建方法, 判断用户的地址是否已经到达２０个
    def create(self, request, *args, **kwargs):
        # # 1,获取参数
        # dict_data = request.data
        #
        # # 2,获取序列化器
        # serializer = self.get_serializer(data=dict_data)
        #
        # # 3,校验入库
        # serializer.is_valid(raise_exception=True)
        # serializer.save()
        #
        # # 4,返回
        # return Response(serializer.data)

        # 获取用户地址数量
        count = request.user.addresses.filter(is_deleted=False).count()

        # 判断地址数量
        if count >= 20:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 调用父类方法即可
        return super(AddressView, self).create(request, *args, **kwargs)

    # 更改用户默认地址
    @action(methods=['put'], detail=True)  # 格式:addresses/pk/status
    def status(self, request, pk):
        request.user.default_address_id = pk
        request.user.save()
        return Response(status=status.HTTP_200_OK)

    # 修改地址的标题
    @action(methods=["put"], detail=True)
    def title(self, request, pk):
        # 1,获取参数
        dict_data = request.data
        address = self.get_object()

        # 2, 创建序列化器
        serializer = serializers.AddressTitleSerializer(instance=address, data=dict_data)

        # 3,校验数据入库
        serializer.is_valid(raise_exception=True)
        serializer.save()

        # 4,返回
        return Response(serializer.data)

    # 4,重写destory方法, 为了逻辑删除
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.is_deleted = True
        instance.save()
        return Response(status=status.HTTP_204_NO_CONTENT)

class TestView(APIView):
    def get(self, request, name, age):
        print(self.kwargs) # 获取的是地址中，携带的资源参数
        return Response("%s, %s" % (name, age))


# 找回密码
# 验证账户名
class CheckUserView(APIView):

    def get(self, request, mobile):
        # 判断用户名或者手机号是否存在
        # 1 获取参数
        d_data = request.query_params.dict()
        d_data['mobile'] = mobile

        # 2 验证参数
        s = serializers.CheckViewSerializer(data=d_data)
        s.is_valid(raise_exception=True)

        # 获取验证后的参数
        dict_data = s.validated_data

        # 判断用户是否存在
        user = dict_data.get('user')
        if not user:
            return Response(status=status.HTTP_404_NOT_FOUND)

        # 获取带有有效期的token
        serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 300)

        # 返回bytes类型
        token = serializer.dumps({'mobile': mobile}).decode()

        return Response({'mobile': user.mobile, 'access_token': token})

# 验证身份
class CheckSmsView(APIView):
    # 1 获取参数
    def get(self, request):

        # 通行证
        access_token = request.query_params.get("access_token")
        # 获取带有有效期的token(加密签名)
        serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 300)
        try:
            dict_data = serializer.loads(access_token)
        except Exception as e:
            return Response({'message': 'access_token已过期'}, status=status.HTTP_400_BAD_REQUEST)

        # 判断请求间隔是否在60s内
        mobile = dict_data.get('mobile')
        redis_conn = get_redis_connection('code')
        flag = redis_conn.get('sms_code_flag_%s' % mobile)
        if flag:
            return Response({'message': '请求过于频繁'}, status=status.HTTP_400_BAD_REQUEST)

        # 3 生成短信验证码，将短信验证码保存在redis缓存中
        sms_code = '%06d' % random.randint(0, 999999)
        print('sms_code:%s' % sms_code)

        # 使用celery发送短信任务
        from celery_tasks.sms.tasks import send_sms_code
        send_sms_code.delay(mobile, sms_code)

        redis_conn.setex('sms_code_%s' % mobile, 300, sms_code)

        return Response({'message': 'ok'})

# 验证身份2
class RestCodeView(APIView):

    # 1,获取参数
    def get(self, request, mobile):
        d_dict = request.query_params.dict()
        d_dict["mobile"] = mobile

        # 2,校验参数
        s = serializers.RestCodeSerializer(data=d_dict)
        s.is_valid(raise_exception=True)

        # 3,获取验证后的参数, 判断用户是否存在
        user = s.validated_data.get("user")
        if not user:
            return Response(status=status.HTTP_404_NOT_FOUND)

        # 4,获取带有有效期的token
        serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 300)

        # 返回bytes类型
        token = serializer.dumps({"user_id": user.id}).decode()
        return Response({"user_id": user.id, "access_token": token})

# 重置密码
class ChangeCodeView(APIView):
    def post(self, request, pk):
        # 获取参数
        d_data = request.data
        access_token = d_data.get("access_token")
        pwd = d_data.get("password")
        pwd2 = d_data.get("password2")

        # 校验参数
        try:
            serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 300)
            token = serializer.loads(access_token)
        except:
            return Response({"message": "access_token过期"}, status=status.HTTP_400_BAD_REQUEST)

        if pwd != pwd2:
            return Response({"message": "两次密码不一致"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            user = User.objects.get(pk=pk)
        except:
            return Response({"message": "用户不存在"}, status=status.HTTP_400_BAD_REQUEST)

        # 检验用户的id是否被篡改过
        if user.id != token.get("user_id"):
            return Response({"message": "OK"})

        # 设置密码
        try:
            user.set_password(pwd)
            user.save()
        except:
            return Response({"message": "数据库错误"}, status=status.HTTP_400_BAD_REQUEST)

        return Response({"message": "OK"})

